from manim import *

class TelescopingSum(Scene):
    def construct(self):
        # 标题
        title = Text("裂项求和").to_edge(UP)
        self.play(Write(title))
        self.wait(1)

        # 分式求和
        formula = MathTex(r"\sum_{k=1}^{n} \frac{1}{k(k+1)}")
        formula.next_to(title, DOWN, buff=0.5)
        self.play(Write(formula))
        self.wait(1)

        # 拆分成两部分
        split_formula = MathTex(r"\frac{1}{k(k+1)} = \frac{1}{k} - \frac{1}{k+1}")
        split_formula.next_to(formula, DOWN, buff=0.5)
        self.play(Write(split_formula))
        self.wait(1)

        # 缩小并移动到左上角
        self.play(
            formula.animate.scale(0.5).to_corner(UP + LEFT).shift(DOWN * 0.5)
        )
        self.play(
            split_formula.animate.scale(0.5).next_to(formula, DOWN, aligned_edge=LEFT)
        )
        self.wait(1)

        # 展示相互抵消
        sum_formula = MathTex(r"\sum_{k=1}^{n} \left( \frac{1}{k} - \frac{1}{k+1} \right)")
        sum_formula.next_to(title, DOWN, buff=1.5)
        self.play(Write(sum_formula))
        self.wait(1)

        # 展示相互抵消的公式
        cancel_formula = MathTex(
            r"= \left( 1 - \frac{1}{2} \right)"
            r"+ \left( \frac{1}{2} - \frac{1}{3} \right)"
            r"+ \cdots + \left( \frac{1}{n} - \frac{1}{n+1} \right)"
        ).scale(0.8)
        cancel_formula.next_to(sum_formula, DOWN, buff=0.5, aligned_edge=LEFT)
        self.play(Write(cancel_formula))
        self.wait(1)

        # 最终结果
        result = MathTex(r"= 1 - \frac{1}{n+1}").scale(0.8)
        result.next_to(cancel_formula, DOWN, buff=0.5, aligned_edge=LEFT)
        self.play(Write(result))
        self.wait(1)

        # 缩小并移动到左上角
        group = VGroup(sum_formula, cancel_formula, result)
        group.arrange(DOWN, aligned_edge=LEFT, buff=0.5)
        self.play(
            group.animate.scale(0.5).next_to(split_formula, DOWN, aligned_edge=LEFT)
        )
        self.wait(1)

        # 结束
        self.play(FadeOut(title), FadeOut(formula), FadeOut(split_formula), FadeOut(group))
        self.wait(1)